<template>
  <div>
    <h3>shallowRef:</h3>
    <p>
      它可以用来设置基本数据类型和引用类型的数据，如果是基本数据类型可以保持数据的响应性；如果是引用类型，会丢失数据的响应性。
    </p>
    <p>state: {{ state }}</p>
    <button @click="setState">setState</button>
  </div>
</template>

<script>
import { shallowRef, ref, reactive, shallowReactive } from "vue";
export default {
  name: "Vue3CourseAPIView",
  setup() {
    /*
    const state = shallowRef({ count: 1 });
    console.log(state); // 内部的对象是Object，没有被转化为Proxy
    // const state = shallowRef("小米");
    const setState = () => {
      // 不会触发更改
      // state.value.count = 2;
      // 会触发更改
      state.value = { count: 2 };
      // state.value = "小红";
    };
    */

    /*
    const state = ref({ count: 1 });
    console.log(state); // 内部的对象Proxy
    // const state = ref("小米");
    const setState = () => {
      // 不会触发更改
      // state.value.count = 2;
      // 会触发更改
      // state.value = { count: 2 };
      // state.value = "小红";
    };
    */

    // 总结：shallowRef 和 ref
    // shallowRef：直接修改 .value 的值，才具备响应式。如果修改的是 .value 对象内部的某个属性值，不具备响应式；
    // ref：直接修改 .value 的值，以及修改 .value 内部对象属性值，都具备响应式；

    // shallowRef 使用场景：
    // 在这种性能负担通常这只有在处理超大型数组或层级很深的对象时，例如一次渲染需要访问 100,000+ 个属性时，shallowRef的作用才会变得比较明显。
    // 1. 数据量较大时，比如长列表，如果使用传统的ref来保存长列表，那么这个列表中嵌套的每一层对象，都会被vue转化为Proxy代理对象，具备深度响应式。这种全部转化Proxy的工作也是非常消耗性能的。而此时使用 shallowRef 只保持.value的响应式，内部属性不再转化Proxy，从而进行性能优化。
    // 2. 一般接口返回的数据，我们不会修改其值，只是展示，可以使用shallowRef或者realonly包裹。如果自定义的对象，后面需要修改对象内部的属性值，此时需要具备深度响应。
    const state = shallowRef({
      name: "one",
      children: [
        {
          name: "two",
          value: "小明",
          other: {
            address: "郑州市",
          },
        },
        {
          name: "two",
          value: "小明",
          other: {
            address: "郑州市",
          },
        },
        {
          name: "two",
          value: "小明",
          other: {
            address: "郑州市",
          },
        },
        {
          name: "two",
          value: "小明",
          other: {
            address: "郑州市",
          },
        },
      ],
    });
    console.log(state);
    const setState = () => {
      // console.log(state.value.children[0]);
      // console.log(state.value.children[0].other);
      // state.value.children[0].other.address = "北京市";
      state.value = { a: 10, b: 20 };
    };
    return {
      state,
      setState,
    };
  },
};
</script>

<style lang="less" scoped></style>
